/**
 * Copyright (c) OpenLens Authors. All rights reserved.
 * Licensed under MIT License. See LICENSE in root directory for more information.
 */

import React from "react";
import { Common, Renderer } from "@k8slens/extensions";
import { nodeShellPreferencesStore } from "./preference/node-shell-preference-store";

type Node = Renderer.K8sApi.Node;

const {
  Component: {
    terminalStore,
    createTerminalTab,
    ConfirmDialog,
    MenuItem,
    Icon,
  },
  Navigation,
  Catalog: {
    CatalogEntityRegistry
  }
} = Renderer;
const {
  App,
} = Common;

export function NodeMenu(props: Renderer.Component.KubeObjectMenuProps<Node>) {
  const { object: node, toolbar } = props;

  if (!node) {
    return null;
  }

  const nodeName = node.getName();
  const kubectlPath = App.Preferences.getKubectlPath() || "kubectl";
  const kubeconfigPath = new CatalogEntityRegistry().activeEntity.spec.kubeconfigPath;

  const sendToTerminal = (command: string) => {
    terminalStore.sendCommand(command, {
      enter: true,
      newTab: true,
    });
    Navigation.hideDetails();
  };

  const shell = () => {
    const customImage = nodeShellPreferencesStore.customImage;
    const imagePullSecret = nodeShellPreferencesStore.imagePullSecret;
    const namespace = nodeShellPreferencesStore.namespace || "default";
    const debugPodName = `node-debugger-${nodeName}`;
    
    // 检查是否已存在调试Pod
    const checkCmd = `${kubectlPath} get pod ${debugPodName} -n ${namespace} --kubeconfig ${kubeconfigPath} --ignore-not-found`;
    
    // 清理旧Pod的命令
    const cleanupCmd = `${kubectlPath} delete pod ${debugPodName} -n ${namespace} --kubeconfig ${kubeconfigPath} --ignore-not-found`;
    
    // 创建新调试Pod的命令
    let createCmd = `${kubectlPath} debug --kubeconfig ${kubeconfigPath} node/${nodeName} -it --image=${customImage} --image-pull-policy=IfNotPresent --pod-running-timeout=5m --name=${debugPodName}`;
    
    if (namespace !== "default") {
      createCmd += ` -n ${namespace}`;
    }
    
    // 完整的shell命令：使用PowerShell兼容语法
    const shellCmd = `
      $pods = & "${kubectlPath}" get pods -n ${namespace} --kubeconfig "${kubeconfigPath}" --no-headers | ForEach-Object { $_.Split()[0] }; $existingPod = @($pods | Where-Object { $_ -like "node-debugger-${nodeName}-*" })[0]; if ($existingPod) { Write-Host "Reusing existing debug pod $existingPod..."; & "${kubectlPath}" exec -it $existingPod -n ${namespace} --kubeconfig "${kubeconfigPath}" -- sh } else { Write-Host "Creating new debug pod..."; & "${kubectlPath}" debug --kubeconfig "${kubeconfigPath}" node/${nodeName} -it --image=${customImage} --image-pull-policy=IfNotPresent${namespace !== "default" ? ` -n ${namespace}` : ""} -- sh }
    `.replace(/\s+/g, ' ').trim();
    
    let messageContent = (
      <div>
        <p>
          {"Open node shell for "}
          <b>{nodeName}</b>
          {" with image "}
          <b>{customImage}</b>
          {" in namespace "}
          <b>{namespace}</b>
        </p>
        {imagePullSecret && imagePullSecret.trim() !== "" && (
          <p style={{ color: "orange" }}>
            <small>
              Note: Ensure imagePullSecret "{imagePullSecret}" exists in namespace "{namespace}"
            </small>
          </p>
        )}
        <p>
          <small>
            This will check for an existing debug pod first. If one exists, it will be reused.
            Otherwise, a new debug pod will be created.
          </small>
        </p>
        <p>
          <small>
            To clean up old debug pods, run: <code>{cleanupCmd}</code>
          </small>
        </p>
      </div>
    );

    ConfirmDialog.open({
      ok: () => sendToTerminal(shellCmd),
      labelOk: `Node Shell`,
      message: messageContent,
    });
  };

  const cordon = () => {
    sendToTerminal(`${kubectlPath} cordon --kubeconfig  ${kubeconfigPath}  ${nodeName}`);
  };

  const unCordon = () => {
    sendToTerminal(`${kubectlPath}  uncordon --kubeconfig ${kubeconfigPath}  ${nodeName}`);
  };

  const drain = () => {
    const command = `${kubectlPath}  drain ${nodeName} --kubeconfig  ${kubeconfigPath}  --delete-local-data --ignore-daemonsets --force`;

    ConfirmDialog.open({
      ok: () => sendToTerminal(command),
      labelOk: `Drain Node`,
      message: (
        <p>
          {"Are you sure you want to drain "}
          <b>{nodeName}</b>
          ?
        </p>
      ),
    });
  };

  const cleanupDebugPods = () => {
    const namespace = nodeShellPreferencesStore.namespace || "default";
    const cleanupCmd = `& "${kubectlPath}" get pods -n "${namespace}" --kubeconfig "${kubeconfigPath}" --no-headers | ForEach-Object { $podName = ($_.Split())[0]; if ($podName -like "node-debugger-*") { & "${kubectlPath}" delete pod $podName -n "${namespace}" --kubeconfig "${kubeconfigPath}" --ignore-not-found } }`;
    
    ConfirmDialog.open({
      ok: () => sendToTerminal(cleanupCmd),
      labelOk: `Clean Up`,
      message: (
        <p>
          {"Clean up all existing debug pods in namespace "}
          <b>{namespace}</b>
          {"?"}
        </p>
      ),
    });
  };

  return (
    <>
      <MenuItem onClick={shell}>
        <Icon
          svg="ssh"
          interactive={toolbar}
          tooltip={toolbar && "Node shell"}
        />
        <span className="title">Shell</span>
      </MenuItem>
      {
        node.isUnschedulable()
          ? (
            <MenuItem onClick={unCordon}>
              <Icon
                material="play_circle_filled"
                tooltip={toolbar && "Uncordon"}
                interactive={toolbar}
              />
              <span className="title">Uncordon</span>
            </MenuItem>
          )
          : (
            <MenuItem onClick={cordon}>
              <Icon
                material="pause_circle_filled"
                tooltip={toolbar && "Cordon"}
                interactive={toolbar}
              />
              <span className="title">Cordon</span>
            </MenuItem>
          )
      }
      <MenuItem onClick={drain}>
        <Icon
          material="delete_sweep"
          tooltip={toolbar && "Drain"}
          interactive={toolbar}
        />
        <span className="title">Drain</span>
      </MenuItem>
      <MenuItem onClick={cleanupDebugPods}>
        <Icon
          material="cleaning_services"
          tooltip={toolbar && "Clean Debug Pods"}
          interactive={toolbar}
        />
        <span className="title">Clean Debug Pods</span>
      </MenuItem>
    </>
  );
}
